{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-11-29T03:18:03.031625Z",
     "start_time": "2018-11-29T03:18:02.964582Z"
    }
   },
   "outputs": [],
   "source": [
    "#可视化树\n",
    "'''\n",
    "Created on Oct 14, 2010\n",
    "@author: Peter Harrington\n",
    "'''\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "decisionNode = dict(boxstyle=\"sawtooth\", fc=\"0.8\")\n",
    "leafNode = dict(boxstyle=\"round4\", fc=\"0.8\")\n",
    "arrow_args = dict(arrowstyle=\"<-\")\n",
    "\n",
    "def getNumLeafs(myTree):\n",
    "    numLeafs = 0\n",
    "    firstStr = list(myTree.keys())[0]\n",
    "    secondDict = myTree[firstStr]\n",
    "    for key in secondDict.keys():\n",
    "        if type(secondDict[key]).__name__=='dict':#test to see if the nodes are dictonaires, if not they are leaf nodes\n",
    "            numLeafs += getNumLeafs(secondDict[key])\n",
    "        else:   numLeafs +=1\n",
    "    return numLeafs\n",
    "\n",
    "def getTreeDepth(myTree):\n",
    "    maxDepth = 0\n",
    "    firstStr = list(myTree.keys())[0]\n",
    "    secondDict = myTree[firstStr]\n",
    "    for key in secondDict.keys():\n",
    "        if type(secondDict[key]).__name__=='dict':#test to see if the nodes are dictonaires, if not they are leaf nodes\n",
    "            thisDepth = 1 + getTreeDepth(secondDict[key])\n",
    "        else:   thisDepth = 1\n",
    "        if thisDepth > maxDepth: maxDepth = thisDepth\n",
    "    return maxDepth\n",
    "\n",
    "def plotNode(nodeTxt, centerPt, parentPt, nodeType):\n",
    "    createPlot.ax1.annotate(nodeTxt, xy=parentPt,  xycoords='axes fraction',\n",
    "             xytext=centerPt, textcoords='axes fraction',\n",
    "             va=\"center\", ha=\"center\", bbox=nodeType, arrowprops=arrow_args )\n",
    "    \n",
    "def plotMidText(cntrPt, parentPt, txtString):\n",
    "    xMid = (parentPt[0]-cntrPt[0])/2.0 + cntrPt[0]\n",
    "    yMid = (parentPt[1]-cntrPt[1])/2.0 + cntrPt[1]\n",
    "    createPlot.ax1.text(xMid, yMid, txtString, va=\"center\", ha=\"center\", rotation=30)\n",
    "\n",
    "def plotTree(myTree, parentPt, nodeTxt):#if the first key tells you what feat was split on\n",
    "    numLeafs = getNumLeafs(myTree)  #this determines the x width of this tree\n",
    "    depth = getTreeDepth(myTree)\n",
    "    firstStr = list(myTree.keys())[0]     #the text label for this node should be this\n",
    "    cntrPt = (plotTree.xOff + (1.0 + float(numLeafs))/2.0/plotTree.totalW, plotTree.yOff)\n",
    "    plotMidText(cntrPt, parentPt, nodeTxt)\n",
    "    plotNode(firstStr, cntrPt, parentPt, decisionNode)\n",
    "    secondDict = myTree[firstStr]\n",
    "    plotTree.yOff = plotTree.yOff - 1.0/plotTree.totalD\n",
    "    for key in secondDict.keys():\n",
    "        if type(secondDict[key]).__name__=='dict':#test to see if the nodes are dictonaires, if not they are leaf nodes   \n",
    "            plotTree(secondDict[key],cntrPt,str(key))        #recursion\n",
    "        else:   #it's a leaf node print the leaf node\n",
    "            plotTree.xOff = plotTree.xOff + 1.0/plotTree.totalW\n",
    "            plotNode(secondDict[key], (plotTree.xOff, plotTree.yOff), cntrPt, leafNode)\n",
    "            plotMidText((plotTree.xOff, plotTree.yOff), cntrPt, str(key))\n",
    "    plotTree.yOff = plotTree.yOff + 1.0/plotTree.totalD\n",
    "#if you do get a dictonary you know it's a tree, and the first element will be another dict\n",
    "\n",
    "def createPlot(inTree):\n",
    "    fig = plt.figure(1, facecolor='white')\n",
    "    fig.clf()\n",
    "    axprops = dict(xticks=[], yticks=[])\n",
    "    createPlot.ax1 = plt.subplot(111, frameon=False, **axprops)    #no ticks\n",
    "    #createPlot.ax1 = plt.subplot(111, frameon=False) #ticks for demo puropses \n",
    "    plotTree.totalW = float(getNumLeafs(inTree))\n",
    "    plotTree.totalD = float(getTreeDepth(inTree))\n",
    "    plotTree.xOff = -0.5/plotTree.totalW; plotTree.yOff = 1.0;\n",
    "    plotTree(inTree, (0.5,1.0), '')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 手写ID3决策树"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-11-29T03:18:07.959818Z",
     "start_time": "2018-11-29T03:18:06.147542Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "no lenses\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "\"\\n#测试数据\\ndef createDataSet():\\n    dataSet = [[1, 1, 'yes'],\\n               [1, 1, 'yes'],\\n               [1, 0, 'no'],\\n               [0, 1, 'no'],\\n               [0, 1, 'no']]\\n    labels = ['no surfacing','flippers']\\n    #change to discrete values\\n    return dataSet, labels\\n\\ndata,feature_names = createDataSet()\\ntree = createTree(data, feature_names)\\nprint(classify(tree, feature_names,[1,0]))\\n\""
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from math import *\n",
    "import operator\n",
    "import pickle\n",
    "\n",
    "#计算熵\n",
    "def entropy(data):\n",
    "    num = len(data)\n",
    "    num_labels ={}\n",
    "    for vec in data:\n",
    "        num_labels[vec[-1]] = num_labels.get(vec[-1],0)+1\n",
    "    ent = 0.0\n",
    "    for key in num_labels.keys():\n",
    "        prob = float(num_labels[key])/num\n",
    "        ent -= prob*log(prob,2)\n",
    "    return ent\n",
    "\n",
    "#根据给定特征划分数据集, axis是特征对应的编号，value是匹配的值\n",
    "def splitDataSet(data, axis, value):\n",
    "    res = []\n",
    "    for vec in data:\n",
    "        if vec[axis] == value:\n",
    "            res.append(vec[:axis] + vec[axis+1:])\n",
    "    return res\n",
    "\n",
    "#遍历数据集，计算每种特征对应的信息增益，选出增益最小的，该特征即为用于分类的特征\n",
    "def chooseFeature(data):\n",
    "    num_feature = len(data[0])-1\n",
    "    #计算H(D)\n",
    "    base_ent = entropy(data)\n",
    "    max_gain = 0.0\n",
    "    best_feature = 0\n",
    "    for i in range(num_feature):\n",
    "        #找出feature的种类\n",
    "        uniqueFeature = set([vec[i] for vec in data])\n",
    "        #对每个feature计算其对应的条件信息熵\n",
    "        sub_ent = 0.0\n",
    "        for feature in uniqueFeature:\n",
    "            sub_data = splitDataSet(data, i, feature)\n",
    "            prob = len(sub_data)/float(len(data))\n",
    "            sub_ent += prob*entropy(sub_data)\n",
    "        #计算每个feature对应的信息增益\n",
    "        gain = base_ent - sub_ent\n",
    "        #选择最大的信息增益，其对应的feature即为最佳的feature\n",
    "        if gain > max_gain:\n",
    "            max_gain = gain\n",
    "            best_feature = i\n",
    "    return best_feature\n",
    "            \n",
    "#递归构建决策树\n",
    "#原始数据集-> 递归地基于最好的属性划分数据集->终止条件：所有属性已经用过或划分后的数据集每个集合只属于一个label,\n",
    "#若所有属性用完但是每个划分属性不都属于一个label，就使用“多数表决”的方法。\n",
    "\n",
    "#多数表决函数\n",
    "def majority(classes):\n",
    "    classCount = {}\n",
    "    for item in classes:\n",
    "        classCount[item] = classCount.get(item,0) + 1\n",
    "    sortedClassesCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse=True)\n",
    "    #返回表决最多的label\n",
    "    return sortedClassCount[0][0]\n",
    "\n",
    "#递归构建树，存入字典中，以便随后的可视化.feature_name是feature的名字，仅是为了可视化方便。\n",
    "def createTree(data, feature_names):\n",
    "    #找出data数据集中所有的labels\n",
    "    classList = [item[-1] for item in data]\n",
    "    #如果只属于一种label，则停止构建树\n",
    "    if len(set(classList)) == 1:\n",
    "        return classList[0]\n",
    "    #若果所有features属性都已经使用完，也停止构建树\n",
    "    #每次用完一个特征都会删除，这样最后数据集data中只剩下最后一位的label位\n",
    "    if len(data[0]) == 1:\n",
    "        return majority(classList)\n",
    "    bestFeat = chooseFeature(data)\n",
    "    bestFeatName = feature_names[bestFeat]\n",
    "    #bestFeatName是用于分离数据集的特征的名字，作为根\n",
    "    tree = {bestFeatName:{}}\n",
    "    #del只删除元素，但是原来的index不变\n",
    "    sub_names = feature_names[:]\n",
    "    del(sub_names[bestFeat])\n",
    "    uniqFeats = set([item[bestFeat] for item in data])\n",
    "    #对于每个feature，递归地构建树\n",
    "    for feature in uniqFeats:\n",
    "        tree[bestFeatName][feature] = createTree(splitDataSet(data,bestFeat,feature), sub_names)\n",
    "    return tree\n",
    "    \n",
    "\n",
    "#分类函数,也是递归地分类（从根到叶节点）\n",
    "def classify(tree, feature_names, test_data):\n",
    "    #找到根，即第一个用于分类的特征\n",
    "    root = list(tree.keys())[0]\n",
    "    #找到根对应的子树\n",
    "    sub_trees = tree[root]\n",
    "    #找出对应该特征的index\n",
    "    feat_index = feature_names.index(root)\n",
    "    #对所有子树，将测试样本划分到属于其的子树\n",
    "    for key in sub_trees.keys():\n",
    "        if test_data[feat_index] == key:\n",
    "            #检查是否还有子树，或者已经到达叶节点\n",
    "            if type(sub_trees[key]).__name__ == 'dict':\n",
    "                #若还可以再分，则继续向下找\n",
    "                return classify(sub_trees[key], feature_names,test_data)\n",
    "            else:\n",
    "                #否则直接返回分的类\n",
    "                return sub_trees[key]\n",
    "\n",
    "#存储树（存储模型）\n",
    "def stroeTree(tree, filename):\n",
    "    fw = open(filename,'w')\n",
    "    pickle.dump(tree,fw)\n",
    "    fw.close()\n",
    "    return\n",
    "   \n",
    "#提取树\n",
    "def grabTree(filename):\n",
    "    fr = open(filename)\n",
    "    return pickle.load(fr)\n",
    "\n",
    "#预测隐形眼镜类型，已知数据集，如何判断患者需要佩戴的眼镜类型\n",
    "fr = open('lenses.txt')\n",
    "lenses = [line.strip().split('\\t') for line in fr.readlines()]\n",
    "feature_names = ['age', 'prescript','astigmatic','tearRate']\n",
    "#构建树\n",
    "tree = createTree(lenses,feature_names)\n",
    "#可视化树\n",
    "createPlot(tree)\n",
    "#测试\n",
    "print(classify(tree,feature_names,['pre','myope','no','reduced']))\n",
    "'''\n",
    "#测试数据\n",
    "def createDataSet():\n",
    "    dataSet = [[1, 1, 'yes'],\n",
    "               [1, 1, 'yes'],\n",
    "               [1, 0, 'no'],\n",
    "               [0, 1, 'no'],\n",
    "               [0, 1, 'no']]\n",
    "    labels = ['no surfacing','flippers']\n",
    "    #change to discrete values\n",
    "    return dataSet, labels\n",
    "\n",
    "data,feature_names = createDataSet()\n",
    "tree = createTree(data, feature_names)\n",
    "print(classify(tree, feature_names,[1,0]))\n",
    "'''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### sklearn分类决策树，使用的是CART树"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2018-11-29T05:39:14.299851Z",
     "start_time": "2018-11-29T05:39:14.257847Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "no lenses\n"
     ]
    }
   ],
   "source": [
    "#sklearn 决策树实现\n",
    "from sklearn import tree\n",
    "\n",
    "def DT(train_data, test_data, train_class):\n",
    "    clf = tree.DecisionTreeClassifier()\n",
    "    clf = clf.fit(train_data, train_class)\n",
    "    return clf.predict(test_data)\n",
    "    \n",
    "fr = open('lenses.txt')\n",
    "lenses = [line.strip().split('\\t') for line in fr.readlines()]\n",
    "#将class的label从源数据集中分离\n",
    "train_data = []\n",
    "train_class = []\n",
    "for lense in lenses:\n",
    "    train_data.append(lense[:len(lense)-1])\n",
    "    train_class.append(lense[-1])\n",
    "test_data = [['pre','myope','no','reduced']]\n",
    "#将string的特征和class标签转化为int型\n",
    "unique_feature = set()\n",
    "unique_label = set()\n",
    "for data in train_data:\n",
    "    for i in range(len(data)):\n",
    "        unique_feature.add(data[i])\n",
    "for i in range(len(train_class)):\n",
    "    unique_label.add(train_class[i])\n",
    "unique_feature = list(unique_feature)\n",
    "unique_label = list(unique_label)\n",
    "for i in range(len(train_data)):\n",
    "    for j in range(len(train_data[i])):\n",
    "        train_data[i][j] = unique_feature.index(train_data[i][j])\n",
    "for i in range(len(train_class)):\n",
    "    train_class[i] = unique_label.index(train_class[i])\n",
    "for i in range(len(test_data)):\n",
    "    for j in range(len(test_data[i])):\n",
    "        test_data[i][j] = unique_feature.index(test_data[i][j])\n",
    "    \n",
    "    \n",
    "print(unique_label[DT(train_data,test_data,train_class)[0]])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.5"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
